home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / dns / resolv+2.1.1 / res_debug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-28  |  10.3 KB  |  506 lines

  1. /*-
  2.  * Copyright (c) 1985, 1990 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted provided
  6.  * that: (1) source distributions retain this entire copyright notice and
  7.  * comment, and (2) distributions including binaries display the following
  8.  * acknowledgement:  ``This product includes software developed by the
  9.  * University of California, Berkeley and its contributors'' in the
  10.  * documentation or other materials provided with the distribution and in
  11.  * all advertising materials mentioning features or use of this software.
  12.  * Neither the name of the University nor the names of its contributors may
  13.  * be used to endorse or promote products derived from this software without
  14.  * specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  16.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  17.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  *
  19.  *    @(#)res_debug.c    5.30 (Berkeley) 6/27/90
  20.  */
  21.  
  22. #if defined(LIBC_SCCS) && !defined(lint)
  23. static char sccsid[] = "@(#)res_debug.c    5.30 (Berkeley) 6/27/90";
  24. #endif /* LIBC_SCCS and not lint */
  25.  
  26. #include <sys/types.h>
  27. #include <netinet/in.h>
  28. #include <stdio.h>
  29. #include <arpa/nameser.h>
  30.  
  31. extern char *p_cdname(), *p_rr(), *p_type(), *p_class(), *p_time();
  32. extern char *inet_ntoa();
  33.  
  34. char *_res_opcodes[] = {
  35.     "QUERY",
  36.     "IQUERY",
  37.     "CQUERYM",
  38.     "CQUERYU",
  39.     "4",
  40.     "5",
  41.     "6",
  42.     "7",
  43.     "8",
  44.     "UPDATEA",
  45.     "UPDATED",
  46.     "UPDATEDA",
  47.     "UPDATEM",
  48.     "UPDATEMA",
  49.     "ZONEINIT",
  50.     "ZONEREF",
  51. };
  52.  
  53. char *_res_resultcodes[] = {
  54.     "NOERROR",
  55.     "FORMERR",
  56.     "SERVFAIL",
  57.     "NXDOMAIN",
  58.     "NOTIMP",
  59.     "REFUSED",
  60.     "6",
  61.     "7",
  62.     "8",
  63.     "9",
  64.     "10",
  65.     "11",
  66.     "12",
  67.     "13",
  68.     "14",
  69.     "NOCHANGE",
  70. };
  71.  
  72. p_query(msg)
  73.     char *msg;
  74. {
  75.     fp_query(msg,stdout);
  76. }
  77.  
  78. /*
  79.  * Print the contents of a query.
  80.  * This is intended to be primarily a debugging routine.
  81.  */
  82. fp_query(msg,file)
  83.     char *msg;
  84.     FILE *file;
  85. {
  86.     register char *cp;
  87.     register HEADER *hp;
  88.     register int n;
  89.  
  90.     /*
  91.      * Print header fields.
  92.      */
  93.     hp = (HEADER *)msg;
  94.     cp = msg + sizeof(HEADER);
  95.     fprintf(file,"HEADER:\n");
  96.     fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]);
  97.     fprintf(file,", id = %d", ntohs(hp->id));
  98.     fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]);
  99.     fprintf(file,"\theader flags: ");
  100.     if (hp->qr)
  101.         fprintf(file," qr");
  102.     if (hp->aa)
  103.         fprintf(file," aa");
  104.     if (hp->tc)
  105.         fprintf(file," tc");
  106.     if (hp->rd)
  107.         fprintf(file," rd");
  108.     if (hp->ra)
  109.         fprintf(file," ra");
  110.     if (hp->pr)
  111.         fprintf(file," pr");
  112.     fprintf(file,"\n\tqdcount = %d", ntohs(hp->qdcount));
  113.     fprintf(file,", ancount = %d", ntohs(hp->ancount));
  114.     fprintf(file,", nscount = %d", ntohs(hp->nscount));
  115.     fprintf(file,", arcount = %d\n\n", ntohs(hp->arcount));
  116.     /*
  117.      * Print question records.
  118.      */
  119.     if (n = ntohs(hp->qdcount)) {
  120.         fprintf(file,"QUESTIONS:\n");
  121.         while (--n >= 0) {
  122.             fprintf(file,"\t");
  123.             cp = p_cdname(cp, msg, file);
  124.             if (cp == NULL)
  125.                 return;
  126.             fprintf(file,", type = %s", p_type(_getshort(cp)));
  127.             cp += sizeof(u_short);
  128.             fprintf(file,", class = %s\n\n", p_class(_getshort(cp)));
  129.             cp += sizeof(u_short);
  130.         }
  131.     }
  132.     /*
  133.      * Print authoritative answer records
  134.      */
  135.     if (n = ntohs(hp->ancount)) {
  136.         fprintf(file,"ANSWERS:\n");
  137.         while (--n >= 0) {
  138.             fprintf(file,"\t");
  139.             cp = p_rr(cp, msg, file);
  140.             if (cp == NULL)
  141.                 return;
  142.         }
  143.     }
  144.     /*
  145.      * print name server records
  146.      */
  147.     if (n = ntohs(hp->nscount)) {
  148.         fprintf(file,"NAME SERVERS:\n");
  149.         while (--n >= 0) {
  150.             fprintf(file,"\t");
  151.             cp = p_rr(cp, msg, file);
  152.             if (cp == NULL)
  153.                 return;
  154.         }
  155.     }
  156.     /*
  157.      * print additional records
  158.      */
  159.     if (n = ntohs(hp->arcount)) {
  160.         fprintf(file,"ADDITIONAL RECORDS:\n");
  161.         while (--n >= 0) {
  162.             fprintf(file,"\t");
  163.             cp = p_rr(cp, msg, file);
  164.             if (cp == NULL)
  165.                 return;
  166.         }
  167.     }
  168. }
  169.  
  170. char *
  171. p_cdname(cp, msg, file)
  172.     char *cp, *msg;
  173.     FILE *file;
  174. {
  175.     char name[MAXDNAME];
  176.     int n;
  177.  
  178.     if ((n = dn_expand(msg, msg + 512, cp, name, sizeof(name))) < 0)
  179.         return (NULL);
  180.     if (name[0] == '\0') {
  181.         name[0] = '.';
  182.         name[1] = '\0';
  183.     }
  184.     fputs(name, file);
  185.     return (cp + n);
  186. }
  187.  
  188. /*
  189.  * Print resource record fields in human readable form.
  190.  */
  191. char *
  192. p_rr(cp, msg, file)
  193.     char *cp, *msg;
  194.     FILE *file;
  195. {
  196.     int type, class, dlen, n, c;
  197.     struct in_addr inaddr;
  198.     char *cp1, *cp2;
  199.  
  200.     if ((cp = p_cdname(cp, msg, file)) == NULL)
  201.         return (NULL);            /* compression error */
  202.     fprintf(file,"\n\ttype = %s", p_type(type = _getshort(cp)));
  203.     cp += sizeof(u_short);
  204.     fprintf(file,", class = %s", p_class(class = _getshort(cp)));
  205.     cp += sizeof(u_short);
  206.     fprintf(file,", ttl = %s", p_time(_getlong(cp)));
  207.     cp += sizeof(u_long);
  208.     fprintf(file,", dlen = %d\n", dlen = _getshort(cp));
  209.     cp += sizeof(u_short);
  210.     cp1 = cp;
  211.     /*
  212.      * Print type specific data, if appropriate
  213.      */
  214.     switch (type) {
  215.     case T_A:
  216.         switch (class) {
  217.         case C_IN:
  218. #ifdef C_HS
  219.         case C_HS:
  220.             bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  221.             if (dlen == 4) {
  222.                 fprintf(file,"\tinternet address = %s\n",
  223.                     inet_ntoa(inaddr));
  224.                 cp += dlen;
  225.             } else if (dlen == 7) {
  226.                 fprintf(file,"\tinternet address = %s",
  227.                     inet_ntoa(inaddr));
  228.                 fprintf(file,", protocol = %d", cp[4]);
  229.                 fprintf(file,", port = %d\n",
  230.                     (cp[5] << 8) + cp[6]);
  231.                 cp += dlen;
  232.             }
  233.             break;
  234. #endif
  235.         default:
  236.             cp += dlen;
  237.         }
  238.         break;
  239.     case T_CNAME:
  240.     case T_MB:
  241.     case T_MG:
  242.     case T_MR:
  243.     case T_NS:
  244.     case T_PTR:
  245.         fprintf(file,"\tdomain name = ");
  246.         cp = p_cdname(cp, msg, file);
  247.         fprintf(file,"\n");
  248.         break;
  249.  
  250.     case T_HINFO:
  251.         if (n = *cp++) {
  252.             fprintf(file,"\tCPU=%.*s\n", n, cp);
  253.             cp += n;
  254.         }
  255.         if (n = *cp++) {
  256.             fprintf(file,"\tOS=%.*s\n", n, cp);
  257.             cp += n;
  258.         }
  259.         break;
  260.  
  261.     case T_SOA:
  262.         fprintf(file,"\torigin = ");
  263.         cp = p_cdname(cp, msg, file);
  264.         fprintf(file,"\n\tmail addr = ");
  265.         cp = p_cdname(cp, msg, file);
  266.         fprintf(file,"\n\tserial = %ld", _getlong(cp));
  267.         cp += sizeof(u_long);
  268.         fprintf(file,"\n\trefresh = %s", p_time(_getlong(cp)));
  269.         cp += sizeof(u_long);
  270.         fprintf(file,"\n\tretry = %s", p_time(_getlong(cp)));
  271.         cp += sizeof(u_long);
  272.         fprintf(file,"\n\texpire = %s", p_time(_getlong(cp)));
  273.         cp += sizeof(u_long);
  274.         fprintf(file,"\n\tmin = %s\n", p_time(_getlong(cp)));
  275.         cp += sizeof(u_long);
  276.         break;
  277.  
  278.     case T_MX:
  279.         fprintf(file,"\tpreference = %ld,",_getshort(cp));
  280.         cp += sizeof(u_short);
  281.         fprintf(file," name = ");
  282.         cp = p_cdname(cp, msg, file);
  283.         break;
  284.  
  285. #ifdef T_TXT
  286.       case T_TXT:
  287.         (void) fputs("\t\"", file);
  288.         cp2 = cp1 + dlen;
  289.         while (cp < cp2) {
  290.             if (n = (unsigned char) *cp++) {
  291.                 for (c = n; c > 0 && cp < cp2; c--)
  292.                     if (*cp == '\n') {
  293.                         (void) putc('\\', file);
  294.                         (void) putc(*cp++, file);
  295.                     } else
  296.                         (void) putc(*cp++, file);
  297.             }
  298.         }
  299.         (void) fputs("\"\n", file);
  300.           break;
  301. #endif
  302.  
  303.     case T_MINFO:
  304.         fprintf(file,"\trequests = ");
  305.         cp = p_cdname(cp, msg, file);
  306.         fprintf(file,"\n\terrors = ");
  307.         cp = p_cdname(cp, msg, file);
  308.         break;
  309.  
  310.     case T_UINFO:
  311.         fprintf(file,"\t%s\n", cp);
  312.         cp += dlen;
  313.         break;
  314.  
  315.     case T_UID:
  316.     case T_GID:
  317.         if (dlen == 4) {
  318.             fprintf(file,"\t%ld\n", _getlong(cp));
  319.             cp += sizeof(int);
  320.         }
  321.         break;
  322.  
  323.     case T_WKS:
  324.         if (dlen < sizeof(u_long) + 1)
  325.             break;
  326.         bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  327.         cp += sizeof(u_long);
  328.         fprintf(file,"\tinternet address = %s, protocol = %d\n\t",
  329.             inet_ntoa(inaddr), *cp++);
  330.         n = 0;
  331.         while (cp < cp1 + dlen) {
  332.             c = *cp++;
  333.             do {
  334.                  if (c & 0200)
  335.                     fprintf(file," %d", n);
  336.                  c <<= 1;
  337.             } while (++n & 07);
  338.         }
  339.         putc('\n',file);
  340.         break;
  341.  
  342. #ifdef ALLOW_T_UNSPEC
  343.     case T_UNSPEC:
  344.         {
  345.             int NumBytes = 8;
  346.             char *DataPtr;
  347.             int i;
  348.  
  349.             if (dlen < NumBytes) NumBytes = dlen;
  350.             fprintf(file, "\tFirst %d bytes of hex data:",
  351.                 NumBytes);
  352.             for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
  353.                 fprintf(file, " %x", *DataPtr);
  354.             fputs("\n", file);
  355.             cp += dlen;
  356.         }
  357.         break;
  358. #endif /* ALLOW_T_UNSPEC */
  359.  
  360.     default:
  361.         fprintf(file,"\t???\n");
  362.         cp += dlen;
  363.     }
  364.     if (cp != cp1 + dlen) {
  365.         fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen);
  366.         cp = NULL;
  367.     }
  368.     fprintf(file,"\n");
  369.     return (cp);
  370. }
  371.  
  372. static    char nbuf[40];
  373.  
  374. /*
  375.  * Return a string for the type
  376.  */
  377. char *
  378. p_type(type)
  379.     int type;
  380. {
  381.     switch (type) {
  382.     case T_A:
  383.         return("A");
  384.     case T_NS:        /* authoritative server */
  385.         return("NS");
  386.     case T_CNAME:        /* canonical name */
  387.         return("CNAME");
  388.     case T_SOA:        /* start of authority zone */
  389.         return("SOA");
  390.     case T_MB:        /* mailbox domain name */
  391.         return("MB");
  392.     case T_MG:        /* mail group member */
  393.         return("MG");
  394.     case T_MR:        /* mail rename name */
  395.         return("MR");
  396.     case T_NULL:        /* null resource record */
  397.         return("NULL");
  398.     case T_WKS:        /* well known service */
  399.         return("WKS");
  400.     case T_PTR:        /* domain name pointer */
  401.         return("PTR");
  402.     case T_HINFO:        /* host information */
  403.         return("HINFO");
  404.     case T_MINFO:        /* mailbox information */
  405.         return("MINFO");
  406.     case T_MX:        /* mail routing info */
  407.         return("MX");
  408. #ifdef T_TXT
  409.     case T_TXT:        /* text */
  410.         return("TXT");
  411. #endif T_TXT
  412.     case T_AXFR:        /* zone transfer */
  413.         return("AXFR");
  414.     case T_MAILB:        /* mail box */
  415.         return("MAILB");
  416.     case T_MAILA:        /* mail address */
  417.         return("MAILA");
  418.     case T_ANY:        /* matches any type */
  419.         return("ANY");
  420.     case T_UINFO:
  421.         return("UINFO");
  422.     case T_UID:
  423.         return("UID");
  424.     case T_GID:
  425.         return("GID");
  426. #ifdef ALLOW_T_UNSPEC
  427.     case T_UNSPEC:
  428.         return("UNSPEC");
  429. #endif /* ALLOW_T_UNSPEC */
  430.     default:
  431.         (void)sprintf(nbuf, "%d", type);
  432.         return(nbuf);
  433.     }
  434. }
  435.  
  436. /*
  437.  * Return a mnemonic for class
  438.  */
  439. char *
  440. p_class(class)
  441.     int class;
  442. {
  443.  
  444.     switch (class) {
  445.     case C_IN:        /* internet class */
  446.         return("IN");
  447. #ifdef C_HS
  448.     case C_HS:        /* hesiod class */
  449.         return("HS");
  450. #endif
  451.     case C_ANY:        /* matches any class */
  452.         return("ANY");
  453.     default:
  454.         (void)sprintf(nbuf, "%d", class);
  455.         return(nbuf);
  456.     }
  457. }
  458.  
  459. /*
  460.  * Return a mnemonic for a time to live
  461.  */
  462. char *
  463. p_time(value)
  464.     u_long value;
  465. {
  466.     int secs, mins, hours;
  467.     register char *p;
  468.  
  469.     if (value == 0) {
  470.         strcpy(nbuf, "0 secs");
  471.         return(nbuf);
  472.     }
  473.  
  474.     secs = value % 60;
  475.     value /= 60;
  476.     mins = value % 60;
  477.     value /= 60;
  478.     hours = value % 24;
  479.     value /= 24;
  480.  
  481. #define    PLURALIZE(x)    x, (x == 1) ? "" : "s"
  482.     p = nbuf;
  483.     if (value) {
  484.         (void)sprintf(p, "%d day%s", PLURALIZE(value));
  485.         while (*++p);
  486.     }
  487.     if (hours) {
  488.         if (value)
  489.             *p++ = ' ';
  490.         (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
  491.         while (*++p);
  492.     }
  493.     if (mins) {
  494.         if (value || hours)
  495.             *p++ = ' ';
  496.         (void)sprintf(p, "%d min%s", PLURALIZE(mins));
  497.         while (*++p);
  498.     }
  499.     if (secs || ! (value || hours || mins)) {
  500.         if (value || hours || mins)
  501.             *p++ = ' ';
  502.         (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
  503.     }
  504.     return(nbuf);
  505. }
  506.